﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.IO;
using Buccaneer;

namespace CustomControls
{
    public class BitmapButton : Panel
    {
        #region Constructor

        public BitmapButton()
        {
            this.Initialize();

            SetStyle(ControlStyles.UserPaint|ControlStyles.AllPaintingInWmPaint|ControlStyles.DoubleBuffer, true);

            strFormat = new StringFormat();
            strFormat.Alignment = StringAlignment.Center;
            strFormat.LineAlignment = StringAlignment.Center;
            
            g = this.CreateGraphics();
            this.OnPaint(null);
        }

        public BitmapButton(string name)
        {
            this.LoadImages(name);
            this.Initialize();
            this.UpdateImage();

            SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.DoubleBuffer, true);

            strFormat = new StringFormat();
            strFormat.Alignment = StringAlignment.Center;
            strFormat.LineAlignment = StringAlignment.Center;
            
            g = this.CreateGraphics();
            this.OnPaint(null);
        }

        public void Initialize()
        {
            this.BackgroundImage = new Bitmap(this.Width, this.Height);
            this.BackColor = Color.Transparent;
            this.picture = new Bitmap(1, 1);
            this.text = "";

            //set events
            this.MouseLeave += new EventHandler(BitmapButton_MouseLeave);
            this.MouseEnter += new EventHandler(BitmapButton_MouseEnter);
            this.MouseDown += new MouseEventHandler(BitmapButton_MouseDown);
            this.MouseUp += new MouseEventHandler(BitmapButton_MouseUp);
            this.GotFocus += new EventHandler(BitmapButton_GotFocus);
        }

        #endregion

        #region OnPaint

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            //*/
            g.DrawImage(
                picture, 
                new Point(
                    (int)((this.Size.Width - (this.Size.Height - (int)(.3 * this.Size.Height))) / 2), 
                    (int)(.1 * this.Size.Height)
                )
            );
            //*/
            g.DrawString(
                text,
                Options.Font,
                Brushes.Black,
                new Rectangle(
                    new Point(0,0),
                    this.Size
                ),
                strFormat
            );
            //*/
        }

        #endregion

        #region Private Attributes

        Graphics g;

        Image normal, hovered, clicked, focussed, disabled, error;
        string text;
        Image picture;
        ButtonState currentState;
        StringFormat strFormat;

        #endregion

        #region Public Attributes

        public Image Image
        {
            get { return BackgroundImage; }
            set { BackgroundImage = value; }
        }

        public Image ImageNormal
        {
            get { return normal; }
        }

        public Image ImageHovered
        {
            get { return hovered; }
        }

        public Image ImageClicked
        {
            get { return clicked; }
        }

        public Image ImageFocussed
        {
            get { return focussed; }
        }

        public Image ImageDisabled
        {
            get { return disabled; }
        }

        public Image Icon
        {
            get { return picture; }
            set
            {
                picture = value;
                this.Refresh();
            }
        }

        public ButtonState CurrentState
        {
            get { return currentState; }
        }

        public override String Text
        {
            get { return text; }
            set { text = value; }
        }

        #endregion

        #region Private Eventhandlers

        void BitmapButton_GotFocus(object sender, EventArgs e)
        {
            if ((byte)currentState < 4)
                changeState(ButtonState.Focussed);
        }

        void BitmapButton_MouseUp(object sender, MouseEventArgs e)
        {
            if ((byte)currentState < 4)
                changeState(ButtonState.Hovered);
        }

        void BitmapButton_MouseEnter(object sender, EventArgs e)
        {
            if ((byte)currentState < 4)
                changeState(ButtonState.Hovered);
        }

        void BitmapButton_MouseDown(object sender, MouseEventArgs e)
        {
            if ((byte)currentState < 4)
                changeState(ButtonState.Clicked);
        }

        void BitmapButton_MouseLeave(object sender, EventArgs e)
        {
            if ((byte)currentState < 4)
                changeState(ButtonState.Normal);
        }

        #endregion

        #region Public Functions

        public void LoadImages(string name)
        {
            // Load all images from Layout Dir
            normal = new Bitmap(Directory.GetCurrentDirectory() + Options.LayoutFolder + name + ".png");
            try
            {
                hovered = new Bitmap(Directory.GetCurrentDirectory() + Options.LayoutFolder + name + "Hover.png");
                clicked = new Bitmap(Directory.GetCurrentDirectory() + Options.LayoutFolder + name + "Click.png");
                focussed = new Bitmap(Directory.GetCurrentDirectory() + Options.LayoutFolder + name + "Focus.png");
                disabled = new Bitmap(Directory.GetCurrentDirectory() + Options.LayoutFolder + name + "Disabled.png");
                error = new Bitmap(Directory.GetCurrentDirectory() + Options.LayoutFolder + name + "Error.png");
            }
            catch (Exception) { }

            this.Size = normal.Size;
        }

        public void UpdateImage()
        {
            Image img;

            switch (currentState)
            {
                case ButtonState.Normal:
                    img = normal;
                    break;
                case ButtonState.Hovered:
                    img = hovered;
                    break;
                case ButtonState.Clicked:
                    img = clicked;
                    break;
                case ButtonState.Focussed:
                    img = focussed;
                    break;
                case ButtonState.Disabled:
                    img = disabled;
                    break;
                default:
                    img = error;
                    break;
            }

            try { Image = new Bitmap(img, this.Size); }
            catch (ArgumentNullException) { }
        }

        public void Disable()
        {
            currentState = ButtonState.Disabled;
            UpdateImage();
        }

        public void Enable()
        {
            currentState = ButtonState.Normal;
            UpdateImage();
        }

        public void SetErrorState(bool error)
        {
            if (error)
                currentState = ButtonState.Error;
            else
                currentState = ButtonState.Normal;
            UpdateImage();
        }

        #endregion

        #region Private Functions

        private void changeState(ButtonState newState)
        {
            currentState = newState;
            UpdateImage();
        }

        #endregion
    }
}
